#include "MessageDispatcher.h"

#include "utils.h"

#include <asm-generic/errno-base.h>
#include <cstddef>
#include <cstdio>
#include <iostream>
#include <memory>
#include <mqueue.h>
#include <mutex>
#include <sys/types.h>
#include <vector>

namespace droneswarm
{

    MessageDispatcher::MessageDispatcher() {}

    MessageDispatcher::~MessageDispatcher() {}

    void MessageDispatcher::registerDispatcher( int fd )
    {
        std::lock_guard< std::mutex > lock( dispatcherMutex_ );
        // lock_guard 简单的锁，会自动释放在器生命周期结束时，但是它没有提供手动解锁的能力。
        // std::shared_lock共享锁，读者可以同时访问，但是写者独占。
        //  std::lock_guard 灵活很多，允许显式地锁定和解锁，可以移动但不可以复制。
        std::vector< BlockOpMsg > fd_data_vector;
        fdDispatcher_[ fd ] = fd_data_vector;
    }
    void MessageDispatcher::cancelFdFromDispatcher( int fd )
    {
        std::lock_guard< std::mutex > lock( dispatcherMutex_ );
        fdDispatcher_.erase( fd );
    }

    bool MessageDispatcher::readToBmsgArray()
    {
        std::lock_guard< std::mutex > lock( dispatcherMutex_ );
        BlockOpMsg bo;
        ssize_t bytes_read;
        int i = 0;
        while ( i < MaxReadCount )
        {
            // bytes_read = mq_receive( mq_, ( char * )&bo, sizeof( bo ), NULL );
            bytes_read = myMqTimeRead( mq_, ( char * )&bo, sizeof( bo ), 10 );
            // std::cout << bytes_read << std::endl;
            if ( bytes_read < 0 )
            {
                if ( bytes_read == -1 )
                {
                    std::cerr << "mq_timedreceive函数参数设置获取" << std::endl;
                    return false;
                }
                else
                {
                    std::cerr << "尝试10次都未接收到数据" << std::endl;
                    return false;
                }
            }
            else
            {
                //解析数据
                int fd = bo.fd;
                fdDispatcher_[ fd ].emplace_back( bo );
                break;
            }
        }
        return true;
    }
    std::vector< BlockOpMsg > MessageDispatcher::dp_receive( int fd )
    {
        //首先读取数据
        bool readRet = readToBmsgArray();

        if ( readRet )
        {
            std::lock_guard< std::mutex > lock( dispatcherMutex_ );
            auto it = fdDispatcher_.find( fd );

            if ( it != fdDispatcher_.end() )
            {

                std::vector< BlockOpMsg > tmp = it->second;
                it->second.clear();
                return tmp;
            }
        }
        return std::vector< BlockOpMsg >();
    }

    bool MessageDispatcher::dp_send( int fd, BlockOpMsg bom, int maxTires )
    {
        // std::cout << bom.data << std::endl;
        ssize_t send_num = myMqTimeSend( mq_, ( char * )&bom, sizeof( bom ), maxTires );
        // {
        //     size_t datalen = bom.data_len;
        //     char realData[ datalen ];
        //     memcpy( realData, bom.data, datalen );
        //     std::cout << realData << std::endl;
        // }

        if ( send_num < 0 )
        {

            if ( send_num == -1 )
            {
                std::cerr << "myMqTimeSend error" << std::endl;
                return false;
            }
            else
            {
                std::cerr << "尝试了" << maxTires << "次都未发送成功" << std::endl;
                return false;
            }
        }
        std::cout << "消息分发器发送数据成功" << std::endl;
        return true;
    }
}  // namespace droneswarm